///////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------

#include <MGLib.h>

#include <TextUtils.h>
#include <Scripts.h>
#include <GUI.h>

#include <Tests.h>
#include <Deferred.h>
#include <SM.h>
#include <CSM.h>
#include <RSM.h>

//-----------------------------------------------------------------------------

Timer t1;
float renderTime;          // elapsed time for render-to-texture
int drawMode = 0;

bool loaded = false;
void Load();

int	toLoad = 1;

//-----------------------------------------------------------------------------

Application::Application()
{
	m_frameTimeLimit = 0;
	SetVSync(false);

    //glShadeModel(GL_SMOOTH);                    // shading mathod: GL_SMOOTH or GL_FLAT
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);      // 4-byte pixel alignment

    // enable /disable features
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
    //glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
    glEnable(GL_DEPTH_TEST);
    //glEnable(GL_LIGHTING);
    glEnable(GL_CULL_FACE);

    // track material ambient and diffuse from surface color, call it before glEnable(GL_COLOR_MATERIAL)
    //glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
    //glEnable(GL_COLOR_MATERIAL);

    glDepthFunc(GL_LEQUAL);
}

//-----------------------------------------------------------------------------

Application::~Application()
{
}

//-----------------------------------------------------------------------------

void	Application::ResolutionChanged()
{
	switch(toLoad)
	{
	case 0:
		SMResolutionChanged();
		break;
	case 1:
		RSMResolutionChanged();
		break;
	}
}

//-----------------------------------------------------------------------------

void	Application::Update(f32 dt)
{
	MGL_CLEAR_PROFILE_SAMPLE();
	{	//main profile
		MGL_PROFILE("Application::Update");

		if( !loaded )
		{
			Load();
			loaded = true;
		}

		InputManager::GetInstance()->Update();

		if( InputManager::GetInstance()->KeyPressed( 27 ) )
		{
			exit(0);
		}

		if( InputManager::GetInstance()->KeyPressed( '`' ) )
		{
			drawMode = (drawMode + 1) % 3;
			if(drawMode == 0)        // fill mode
			{
				glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
				glEnable(GL_DEPTH_TEST);
				glEnable(GL_CULL_FACE);
			}
			else if(drawMode == 1)  // wireframe mode
			{
				glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
				glDisable(GL_DEPTH_TEST);
				glDisable(GL_CULL_FACE);
			}
			else                    // point mode
			{
				glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
				glDisable(GL_DEPTH_TEST);
				glDisable(GL_CULL_FACE);
			}
		}

		GUIInput();

		switch(toLoad)
		{
		case 0:
			SMInput();
			break;
		case 1:
			RSMInput();
			break;
		}

		ScriptsInput();

		switch(toLoad)
		{
		case 0:
			SMUpdate( dt );
			break;
		case 1:
			RSMUpdate( dt );
			break;
		}

		// render /////////////////////////////////////////////////////////////////

		t1.start();

		switch(toLoad)
		{
		case 0:
			SMDraw();
			break;
		case 1:
			RSMDraw();
			break;
		}

		// measure the elapsed time of render-to-texture
		t1.stop();
		renderTime = t1.getElapsedTimeInMilliSec();
		///////////////////////////////////////////////////////////////////////////

		GUIDraw();

		// draw info messages
//#if !defined(LINUX)
		showInfo(renderTime);
		showFPS(dt);
//#endif

	}	//main profile
	MGL_DISPLAY_PROFILE_SAMPLE();
}

//-----------------------------------------------------------------------------

void Load()
{

	switch(toLoad)
	{
	case 0:
		SMLoad();
		break;
	case 1:
		RSMLoad();
		break;
	}

//-----------------------------------------------------------------------------

	//ScriptsLoad( g_scene );

//-----------------------------------------------------------------------------
	
	//GUILoad();

//-----------------------------------------------------------------------------

	//vbiTest(g_scene);

//-----------------------------------------------------------------------------

	//matrixTest();

//-----------------------------------------------------------------------------

	refTests();
}

//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
